package com.tanhua.gateway.filters;

import com.alibaba.fastjson.JSON;
import com.tanhua.commons.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * 自定义网关过滤器
 *  1.实现两个接口 GlobalFilter, Ordered
 *  2.实现两个接口的方法 filter,getOrder
 *  3.将自定义类交给容器管理
 *  4. 编写过滤器的核心方法filter
 * */
@Component
public class AuthFilter implements GlobalFilter, Ordered {

    //存放所有不需要验证的url,自动根据“，”分割为数组
    @Value("${gateway.excludedUrls}")
    private List<String> excludeUrls;

    /**
     * 核心过滤方法
     *  exchange：请求上下文对象（获取request，response）
     *  chain：过滤器链
     */
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //1 判断当前的请求连接是否需要鉴权
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();//请求链接/login

        //2 不需要 直接放行
        if (excludeUrls.contains(path)){
            return chain.filter(exchange);
        }

        //3 需要 鉴权
        HttpHeaders headers = request.getHeaders();
        String token = headers.getFirst("Authorization");

        //针对前端页面发送的token前缀,"Bearer"处理
        if (!StringUtils.isEmpty(token)){
            token=token.replaceAll("Bearer","");
        }

        //4 验证token
        boolean verifyToken = JwtUtils.verifyToken(token);

        if (verifyToken){
            //6 token 正确 放行
            return chain.filter(exchange);
        }

        //5 token失效或错误,异常 拦截返回状态码401
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.UNAUTHORIZED);

        //狗仔返回值
        //return response.setComplete();

        //当公司要求需要响应Json字符串
        //返回一个500，返回401。需要响应Json字符串 {“”:"","":""}
        Map map=new HashMap();
        map.put("errCode",401);
        map.put("errMessage","用户未登录");
        //设置相应格式  固定用法 直接copy
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        byte[] data = JSON.toJSONBytes(map);
        DataBuffer buffer = response.bufferFactory().wrap(data); //数据DatBuffer
        return response.writeWith(Mono.just(buffer));
    }

    /**
     * 配置过滤器的执行顺序
     *    值越大，执行顺序越低
     */
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}
